package org.yo.router.api.launcher;

import android.app.Application;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;


import org.yo.router.annotation.common.CompilerUtil;
import org.yo.router.annotation.framework.ApplicationAble;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * @author hailong
 * @date 2021年11月01日 6:34 下午
 * <p>
 * You never know what you can do until you try !
 * ----------------------------------------------------------------
 */
public class ApplicationAbleManager implements ApplicationAble {


    private List<ApplicationAble> appAbleList = new ArrayList<>();


    private final List<ApplicationAble> appAbles;

    private ApplicationAbleManager() {
        appAbles = new ArrayList<>();
    }

    private static final class Holder {
        public static final ApplicationAbleManager COMPONENT_APP_SDK = new ApplicationAbleManager();
    }

    public static ApplicationAble getInstance() {
        return Holder.COMPONENT_APP_SDK;
    }

    @Override
    public void onCreate(Object context) {
        if (!(context instanceof Application)) {
            return;
        }
        try {
            Application application = (Application) context;
            ApplicationInfo applicationInfo = application.getPackageManager().getApplicationInfo(application.getPackageName(), PackageManager.GET_META_DATA);
            Bundle metaData = applicationInfo.metaData;
            if (metaData == null) {
                return;
            }
            Set<String> keys = metaData.keySet();
            if (null == keys || keys.isEmpty()) {
                return;
            }
            for (String key : keys) {
                if (CompilerUtil.isTagMetaKey(key)) {
                    String value = metaData.getString(key);
                    String qualifyName = CompilerUtil.assemblePackageClassName(value);
                    Class<ApplicationAble> appAbleClazz = (Class<ApplicationAble>) Class.forName(qualifyName);
                    ApplicationAble appAbleInstance = appAbleClazz.newInstance();
                    appAbles.add(appAbleInstance);
                }
            }
            Collections.sort(appAbles);
            for (ApplicationAble appAble : appAbles) {
                appAble.onCreate(application);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onLowMemory() {
        for (ApplicationAble applicationAble : appAbleList) {
            applicationAble.onLowMemory();
        }
    }

    @Override
    public void onTerminate() {
        for (ApplicationAble applicationAble : appAbleList) {
            applicationAble.onTerminate();
        }
    }

    @Override
    public void onConfigurationChanged(Object config) {
        for (ApplicationAble applicationAble : appAbleList) {
            applicationAble.onConfigurationChanged(config);
        }
    }
}
